home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2010 Summer - Disc 1 / WN_Ete2010_CD1.iso / Onglet5 / Weezo / Weezo setup.exe / {code_appDir} / www / includes / transferFunctions.php < prev    next >
PHP Script  |  2010-05-19  |  43KB  |  978 lines

  1. <?php
  2. /**
  3.  * Transfers (uploads, remote downloads) visualisation scripts
  4.  * Includes :
  5.  * - transfer class
  6.  * - transfer misc functions
  7.  * - a page display script divided into 2 parts :
  8.  *     - display in a frame (with head and body stuff), self-refreshed with async requests, for inclusion by explorer pages
  9.  *     - display in div, for inclusion by administration / transfers page
  10.  *
  11.  * Images : view, slideshow, next, prev, fullSize
  12.  * HTML : view webpage (and not source code)
  13.  * text : inline view
  14.  * other formats : download (Opera) or inline view if possible (IE)
  15.  *
  16. * parameters : POST data1 (file directory),  data2 (file name),  data3 (="view"),  data4 (action (optional)),  data5 (parameters (optional))
  17.  *
  18.  * PHP version 5
  19.  *
  20.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  21.  * that is available through the world-wide-web at the following URI:
  22.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  23.  * the PHP License and are unable to obtain it through the web, please
  24.  * send a note to license@php.net so we can mail you a copy immediately.
  25.  *
  26.  * @category   NA
  27.  * @package    NA
  28.  * @author     Nicolas Bruley / Peer 2 World <contact@weezo.net>
  29.  * @copyright  2005-2009 Nicolas Bruley / Peer 2 World
  30.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  31.  * @version    CVS: $Id:$
  32.  * @link       http://www.weezo.net
  33.  * @since      File available since Release 1.0.0
  34.  */
  35.  
  36. /*
  37.  ***************************************************************************************************************************
  38.  * Transfer Class
  39.  ***************************************************************************************************************************
  40.  */
  41. class transfer{
  42.     // Common variables
  43.     public $id; // (unique) Id of transfer
  44.     public $sessionId; // Session ID of user requesting transfer
  45.     public $sessionIP; // IP adress of user who initiated the transfer
  46.     public $type; // 'remoteDownload', 'upload', 'download', or 'bittorrentDownload'
  47.     public $status; // Transfer status
  48.     public $size; // Transfer total size
  49.  
  50.     /*
  51.      * status values :
  52.      *          created = 0
  53.         *         waitConfirm = 1
  54.         *         waitConnection = 2
  55.         *         running = 3
  56.         *         finished = 4
  57.      *         paused = 5
  58.      *         canceled = 6
  59.      *         connecting = 7
  60.      *         failed = 8
  61.      *         removed = 9
  62.      */
  63.     public $updateInterval; // Transfer update-to-file interval, in seconds (used for download monitoring)
  64.  
  65.     // Common
  66.     public $progress; // transfer progress (0-1)
  67.     public $destinationFile; // Destination file (all transfers)
  68.  
  69.     // Remote download and upload specific
  70.     public $destinationDir; // Destination directory (remoteDownload & updload)
  71.  
  72.     // Remote download & download & bittorrent download specific
  73.     public $sourceFile;
  74.  
  75.     // Remote download specific
  76.     public $URL;
  77.     public $host;
  78.     public $path;
  79.  
  80.     // bittorrent download specific
  81.     public $userId; // (unique) id of user used to create torrent file. Used for speed limitation purposes
  82.     public $infoHash; // Url encoded 20 bytes SHA1 hash of bencoded torrent's info dictionnary
  83.     public $trackerIdSet; // True if "tracker id" sent to client
  84.     public $filesOffsets; // list of files and offsets. Format : file_path:eof_offset|file_path:eof_offset|...
  85.     public $pieces; // Number of pieces in torrent
  86.     public $pieceLength; // Piece size, in bytes
  87.     public $sentDataLength; // Nb of bytes sent
  88.     public $linkedTransferToken;// id of linked directLink or publishDownload token
  89.  
  90.     // Constructor
  91.     function __construct($transferType){
  92.         if($transferType=='remoteDownload') $this->id="RDL";
  93.         elseif($transferType=='upload')    $this->id="UL";
  94.         elseif($transferType=='download') $this->id="DL";
  95.         elseif($transferType=='multipleDownload') $this->id="MDL";
  96.         elseif($transferType=='bittorrentDownload') $this->id="BTDL";
  97.         else return false;
  98.  
  99.         $this->id.=rand(0,999999999);
  100.         $this->type=$transferType;
  101.         $this->sessionId=wSession_id();
  102.         $this->sessionIP=$_SERVER['REMOTE_ADDR'];
  103.         $this->status=0;
  104.         $this->progress=0;
  105.         if($transferType=='upload') $this->updateInterval=0.1; else $this->updateInterval=3;
  106.         $this->startTime=time();
  107.         $this->destinationDir=false;
  108.         $this->destinationFile=false;
  109.         $this->sourceFile=false;
  110.         $this->URL=false;
  111.         $this->host=false;
  112.         $this->path=false;
  113.         $this->userId=false;
  114.         $this->infoHash=false;
  115.         $this->pieces=false;
  116.         $this->pieceLength=false;
  117.         $this->trackerIdSet=false;
  118.         $this->sentDataLength=0;
  119.         $this->linkedTransferToken=false;
  120.         $this->lastUpdated=time();
  121.         return $this->id;
  122.     }
  123.  
  124.     // Destructor
  125.     function __destruct(){}
  126.  
  127.     // Transfer "detail" string
  128.     public function detail($useBR=false){
  129.         $output='';
  130.         if($this->type=='upload') {
  131.             $output .= cfCaption('genFileUpload')."<br>\n";
  132.             $output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
  133.             $output .= cfCaption('transferCfgSource').cfCaption('genSeparator').$this->sessionIP.'://?/'.cfUTF8Encode($this->sourceFile)."<br>\n";
  134.             $output .= cfCaption('transferCfgDest').cfCaption('genSeparator').cfUTF8Encode($this->destinationDir.'/'.$this->destinationFile."<br>\n");
  135.             $output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
  136.         }
  137.         elseif($this->type=='download') {
  138.             $output .= cfCaption('transfersDownload')."<br>\n";
  139.             $output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
  140.             $output .= cfCaption('transferCfgSource').cfCaption('genSeparator').cfUTF8Encode($this->sourceFile."<br>\n");
  141.             $output .= cfCaption('transferCfgDest').cfCaption('genSeparator').$this->sessionIP.'://?/'.cfUTF8Encode(basename($this->sourceFile))."<br>\n";
  142.             $output .= cfCaption('genState').cfCaption('genSeparator').($this->captionStatus()).' ('.floor(100*$this->progress).'%)'."<br>\n";
  143.         }
  144.         elseif($this->type=='remoteDownload') {
  145.             $output .= cfCaption('genDirectDownload')."<br>\n";
  146.             $output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
  147.             $output .= cfCaption('transferCfgSource').cfCaption('genSeparator').cfUTF8Encode($this->URL)."<br>\n";
  148.             $output .= cfCaption('transferCfgDest').cfCaption('genSeparator').cfUTF8Encode($this->destinationFile)."<br>\n";
  149.             $output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
  150.         }
  151.         elseif($this->type=='multipleDownload') {
  152.             $output .= cfCaption('explorerMultipleDownload')."<br>\n";
  153.             $output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
  154.             $output .= cfCaption('transferCfgSource').cfCaption('genSeparator').cfUTF8Encode($this->sourceFile)."<br>\n";
  155.             $output .= cfCaption('transferCfgDest').cfCaption('genSeparator').cfUTF8Encode($this->destinationFile)."<br>\n";
  156.             $output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
  157.         }
  158.         elseif($this->type=='bittorrentDownload') {
  159.             $output .= 'Bittorrent'."<br>\n";
  160.             $output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
  161.             $output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
  162.  
  163.             $output .= cfCaption('transferCfgSource').cfCaption('genSeparator')."<br>\n";
  164.             foreach (explode('|',$this->sourceFile) as $file) if($file!='') $output.=' - '.cfUTF8Encode($file)."<br>\n";
  165.             require_once(INCLUDE_DIR.'explorerFunctions.php');
  166.             $output .= cfCaption('genSize').cfCaption('genSeparator').efFileSizeFormat($this->size);
  167.         }
  168.         if($useBR)    return  ($output); else return str_replace("\n",'',$output);
  169.     }
  170.  
  171.     /**
  172.      * save upload in uploads.txt file or to memory
  173.      * @param array $transfersArray: whole array of transfers. If omitted, reload from memory or file
  174.      * @param boolean $commitToFile: true to force commit to file, false to save to memory only
  175.      */
  176.     public function commitToFile($transfersArray=false,$commitToFile=true){
  177.         if(!$transfersArray) $transfersArray=tReadTransfersFiles();
  178.         $transfersArray[$this->id]=$this;
  179.         $result=tWritePHPTransfersFile($transfersArray,$commitToFile);
  180.         unset($transfersArray);
  181.         return $result;
  182.     }
  183.  
  184.     /**
  185.      * @desc Check if transfer is still in transfers array or if it has been removed
  186.      *
  187.      * @return boolean true if still in transfers array
  188.      */
  189.     public function exists(){
  190.         $transfers=tReadTransfersFiles(false);
  191.         return isset($transfers[$this->id]);
  192.     }
  193.  
  194.     /**
  195.      * @desc Return status label (non-utf8 encoded)
  196.      *
  197.      * @return string status
  198.      */
  199.     public function captionStatus(){
  200.         switch ($this->status){
  201.             case 1: return cfCaption('transfersWaitConfirm');
  202.             case 2: return cfCaption('transfersWaitConnection');
  203.             case 3: return cfCaption('transfersWorking');
  204.             case 4: return cfCaption('transfersFinished');
  205.             case 5: return cfCaption('transfersPaused');
  206.             case 6: return cfCaption('transfersCanceled');
  207.             case 7: return cfCaption('transfersConnecting');
  208.             case 8: return cfCaption('transfersFailed');
  209.         }
  210.     }
  211.  
  212.     // Return true if transfer display needs to be consistently refreshed (depending on status)
  213.     public function needRefresh(){
  214.         if($this->status==0 || $this->status==2 || $this->status==3 || $this->status==7 || $this->status==9) return true;
  215.         return false;
  216.     }
  217.  
  218.     // Stop transfer
  219.     public function stop(){
  220.         // Ask application to stop transfer
  221.         if($this->type=='remoteDownload' || $this->type=='fileTransfer') cfServerSendCommand('transfer action="cancel" transferId="'.$this->id.'"');
  222.         else $this->status=9;
  223.         return true;
  224.     }
  225.  
  226.     // Remove finished transfer from list (or even if not finished if $forceRemove)
  227.     public function clear($forceRemove=false){
  228.         if($forceRemove || ($this->status==4 || $this->status==6 || $this->status==8)) {
  229.             // Ask application to remove transfer from list
  230.             if($this->type=='remoteDownload') cfServerSendCommand('transfer action="clear" transferId="'.$this->id.'"');
  231.             else $this->status=9;
  232.             return true;
  233.         }
  234.         return false;
  235.     }
  236.  
  237.     /**
  238.      * @desc Update transfer progress
  239.      * @param float $newProgress : new progress (0-1)
  240.      * @param boolean $commitToFile : set to true to save transfers to file
  241.      */
  242.     public function updateProgress($newProgress, $commitToFile=false){
  243.         if(!is_numeric($newProgress)) return false;
  244.         $this->progress=max(0,min(1,$newProgress));
  245.         $this->lastUpdated=time();
  246.         if($commitToFile) $this->commitToFile();
  247.         return $this->progress;
  248.     }
  249.  
  250.     /**
  251.      * @desc Update transfer status
  252.      * @param integer $newStatus : new status
  253.      * status values :
  254.      *          created = 0
  255.         *         waitConfirm = 1
  256.         *         waitConnection = 2
  257.         *         running = 3
  258.         *         finished = 4
  259.      *         paused = 5
  260.      *         canceled = 6
  261.      *         connecting = 7
  262.      *         failed = 8
  263.      *         removed = 9
  264.      * @param boolean $commitToFile : set to true to save transfers to file
  265.      */
  266.     public function updateStatus($newStatus, $commitToFile=false){
  267.         if(!is_numeric($newStatus)) return false;
  268.         $this->status=$newStatus;
  269.         $this->lastUpdated=time();
  270.         if($commitToFile) $this->commitToFile();
  271.     }
  272.  
  273.     /**
  274.  * @desc display a progress bar with title and text % progress
  275.  *
  276.  * @param mixed $progress : progress value (0-1) or 'U' if unknown (for uploads)
  277.  * @param integer $width : width of progressbar in px
  278.  * @param integer $height : height of progressbar in px
  279.  */
  280.     public function tProgressBar($width){
  281.         // If transfer is upload, update progress from file... when uploadprogress extension will work.
  282.         if(false && $this->type=='upload'){
  283.             $ul_info = uploadprogress_get_info($this->id);
  284.             if(!$ul_info || !isset($ul_info['bytes_total']) || $ul_info['bytes_total']==0) $progress='U';
  285.             else $progress=$ul_info['bytes_total']/$ul_info['bytes_total'];
  286.         }
  287.         $progress=$this->progress;
  288.         $title=$this->captionStatus();
  289.         if(!is_numeric($progress)) {
  290.             $progress='U';
  291.             //$output= '<span title="'.$title.'">';
  292.         }
  293.         else{
  294.             if($progress<0) $progress=0;
  295.             if($progress>1) $progress=1;
  296.             //$output='<span title="'.$title.'">';
  297.         }
  298.         if($progress!=0 && $progress!=1) $title=(round(100*$progress)).'%';
  299.         if($this->status==6 || $this->status==8 || $this->status==9) return outProgressBar(-1,$width,($title),false,false);
  300.         else return outProgressBar($progress,$width,$title,false,false);
  301.     }
  302. }
  303.  
  304. /**
  305.  * @desc cross-session transfer speed limitation
  306.  *         Used to set a user (group) level download speed limit
  307.  *
  308.  */
  309. class transferLimitation{
  310.     private $userId; // Transfer user id
  311.     private $maxTransferRate; // Maximum transfer rate, in KB/sec
  312.     private $totalTransfered;
  313.  
  314.     /**
  315.      * @desc Constructor
  316.      *
  317.      * @param integer $speedLimit : speed limit, bytes per second
  318.      */
  319.     function __construct($speedLimit=-1){
  320.         $totalTransfered=0;
  321.         // User Id
  322.         if(isset($_SESSION['user']['id'])) $this->userId=$_SESSION['user']['id'];
  323.         else $this->userId=$_SERVER['REMOTE_ADDR'];
  324.  
  325.         // Max transfer rate
  326.         if($speedLimit!=-1 && is_numeric($speedLimit)) $this->maxTransferRate=$speedLimit;
  327.         else{
  328.             $this->maxTransferRate=0;
  329.             if(isset($_SESSION['user']['downloadSpeedLimit']) && is_numeric($_SESSION['user']['downloadSpeedLimit']) && $_SESSION['user']['downloadSpeedLimit']!=0) $this->maxTransferRate=$_SESSION['user']['downloadSpeedLimit'];
  330.         }
  331.         if($this->maxTransferRate) customTLCreate($this->userId, time(), $this->maxTransferRate);
  332.     }
  333.  
  334.  
  335.     // Destructor
  336.     function __destruct(){customTLDestroy($this->userId, time());}
  337.  
  338.     /**
  339.      * @desc Update speed limit
  340.      *
  341.      * @param unknown_type $speedLimit
  342.      */
  343.     function setSpeedLimit($speedLimit){
  344.         if($this->maxTransferRate==$speedLimit) return;
  345.         $this->maxTransferRate=$speedLimit;
  346.         customTLUpdate($this->userId, time(), $speedLimit);
  347.     }
  348.  
  349.     /**
  350.      * @desc Indicate new data has been transfered, and wait until average transfer rate is below max transfer rate
  351.      * @param integer $nbBytes : number of bytes sent
  352.      * @param boolean $isTotal : true if $nbBytes is total sent, false if $nbBytes is new data sent
  353.      * @param boolean $blocking : true if this function should include tempo
  354.      */
  355.     public function addData($nbBytes, $isTotal=false, $blocking=true) {
  356.         if(!$this->maxTransferRate) return;
  357.         if($isTotal){
  358.             customTLAddData($this->userId, time(),$nbBytes - $this->totalTransfered);
  359.             $this->totalTransfered=$nbBytes;
  360.         }
  361.         else{
  362.             customTLAddData($this->userId, time(),$nbBytes);
  363.             $this->totalTransfered+=$nbBytes;
  364.         }
  365.         // Wait until average transfer rate is below max transfer rate
  366.         if($blocking) {while (!customTLIsReady($this->userId, time())) usleep(300000);}
  367.     }
  368.     /**
  369.      * @desc Return true if data can be sent, false if over limit
  370.      *
  371.      * @return boolean
  372.      */
  373.     public function isReady(){return customTLIsReady($this->userId, time());}
  374.     public function debugView(){
  375.         customTest($this->userId);
  376.     }
  377. }
  378.  
  379. /**
  380.  * @desc write uploads and downloads into transfer file (data dir /uploads.txt)
  381.                  overwrite all transfers with $transfersArray
  382.  *
  383.  * @param array $transfersArray: array of transfers to write
  384.  * @param mixed $commitToFile:
  385.  *             set to true to save to disk & memory, false to save to memory only, 'time' to commit only if last commit is old enough
  386.  * @return string : time.microtime of save
  387.  */
  388. function tWritePHPTransfersFile($transfersArray, $commitToFile=true){
  389.  
  390.     // Clear finished transfers and detect aborted downloads
  391.     foreach ($transfersArray as $key=>$value){
  392.         if($value->status==9) unset($transfersArray[$key]);
  393.         // Detect aborted downloads
  394.         if($value->type=='download' && $value->status==3 && (time()-$value->lastUpdated)>(2*$value->updateInterval)) {
  395.             $transfersArray[$key]->status=6;
  396.         }
  397.     }
  398.  
  399.     // Transfer saved time
  400.     $time=time().'.'.microtime();
  401.  
  402.     // Save to memory
  403.     cfMSetVar('weezoTransfers',$transfersArray);
  404.  
  405.     $lastSave=(int)cfMGetVar('weezoTransfersLastUpdate');
  406.     cfMSetVar('weezoTransfersLastUpdate',$time);
  407.  
  408.     // Check if upload.txt file must be updated
  409.     if($commitToFile===false || ($commitToFile=='time' && time()-$lastSave<cfHGetVar('transfersFileUpdateInterval',3))) return $time;
  410.  
  411.     if(!$handle=fopen(cfAppDataDir().'/uploads.txt','w')) return false;
  412.  
  413.     // Write uploads, downloads and bittorrent downloads (if status is not 'cleared' (9))
  414.     foreach ($transfersArray as $value){
  415.         if(($value->type=='upload' || $value->type=='download' || $value->type=='bittorrentDownload' || $value->type=='multipleDownload') && $value->status!=9){
  416.             fwrite($handle, '['.$value->id."]\n");
  417.             fwrite($handle, 'type='.$value->type."\n");
  418.             fwrite($handle, 'sessionId='.$value->sessionId."\n");
  419.             fwrite($handle, 'sessionIP='.$value->sessionIP."\n");
  420.  
  421.             // Detect aborted downloads and multiple downloads
  422.             if(($value->type=='download' ||$value->type=='multipleDownload') && $value->status==3 && (time()-$value->lastUpdated)>(2*$value->updateInterval)) $value->status=6;
  423.  
  424.             fwrite($handle, 'status='.$value->status."\n");
  425.             fwrite($handle, 'progress='.$value->progress."\n");
  426.             fwrite($handle, 'size='.$value->size."\n");
  427.             fwrite($handle, 'startTime='.$value->startTime."\n");
  428.             fwrite($handle, 'lastUpdated='.$value->lastUpdated."\n");
  429.             if($value->sourceFile) fwrite($handle, 'sourceFile='.$value->sourceFile."\n");
  430.             fwrite($handle, 'destinationFile='.$value->destinationFile."\n");
  431.             if($value->type=='upload') fwrite($handle, 'destinationDir='.$value->destinationDir."\n");
  432.  
  433.             // Bittorrent download specific
  434.             if($value->infoHash) fwrite($handle, 'infoHash='.$value->infoHash."\n");
  435.             if($value->trackerIdSet) fwrite($handle, 'trackerIdSet=true'."\n");
  436.             if($value->userId) fwrite($handle, 'userId='.$value->userId."\n");
  437.             if($value->filesOffsets) fwrite($handle, 'filesOffsets='.$value->filesOffsets."\n");
  438.             if($value->pieces) fwrite($handle, 'pieces='.$value->pieces."\n");
  439.             if($value->pieceLength) fwrite($handle, 'pieceLength='.$value->pieceLength."\n");
  440.             if($value->linkedTransferToken) fwrite($handle, 'linkedTransferToken='.$value->linkedTransferToken."\n");
  441.             if($value->sentDataLength) fwrite($handle, 'sentDataLength='.$value->sentDataLength."\n");
  442.  
  443.             fwrite($handle,"\n");
  444.         }
  445.     }
  446.     fclose($handle);
  447.     return $time;
  448. }
  449.  
  450. /**
  451.  * @desc parse transfers file and return an array of transfers
  452.  * @param boolean $forceReadFromFile : set to true to ignore memory cache
  453.  * @return array : read transfers
  454.  */
  455. function tReadTransfersFiles($forceReadFromFile=false){
  456.     $transfersArray=array();
  457.  
  458.     // If already loaded, read from memory
  459.     if(cfMIssetVar('weezoTransfers') && !$forceReadFromFile){
  460.         $parsedFile2=cfMGetVar('weezoTransfers');
  461.         foreach ($parsedFile2 as $id=>$value) if($value->type=='remoteDownload') unset($parsedFile2[$id]);
  462.     }
  463.     // Else read uploads and downloads file
  464.     else {if(!$parsedFile2=cfParse_ini_file(cfAppDataDir().'/uploads.txt',true)) $parsedFile2=array();}
  465.  
  466.     // Read remote downloads file
  467.     if(!$parsedFile=cfParse_ini_file(cfAppDataDir().'/transfers.txt',true)) $parsedFile=array();
  468.  
  469.     // Initialize last update if not set
  470.     if(!cfMIssetVar('weezoTransfersLastUpdate')) cfMSetVar('weezoTransfersLastUpdate',time().'.'.microtime());
  471.  
  472.  
  473.     // Browse merged files
  474.     foreach (array_merge($parsedFile, $parsedFile2) as $id=>$value){
  475.         if(!is_array($value)) $transfersArray[$id]=$value;
  476.         elseif(isset($value['type'])){
  477.             $transfersArray[$id]=new transfer($value['type']);
  478.             $transfersArray[$id]->id=$id;
  479.             $transfersArray[$id]->type=$value['type'];
  480.             if(isset($value['sessionId'])) $transfersArray[$id]->sessionId=$value['sessionId'];
  481.             if(isset($value['sessionIP'])) $transfersArray[$id]->sessionIP=$value['sessionIP'];
  482.             if(isset($value['status'])) $transfersArray[$id]->status=$value['status'];
  483.             if(isset($value['progress'])) $transfersArray[$id]->progress=str_replace(',','.',$value['progress']);
  484.             if(isset($value['lastUpdated'])) $transfersArray[$id]->lastUpdated=$value['lastUpdated'];
  485.             if(isset($value['startTime'])) $transfersArray[$id]->startTime=$value['startTime'];
  486.             if(isset($value['infoHash'])) $transfersArray[$id]->infoHash=$value['infoHash'];
  487.             if(isset($value['filesOffsets'])) $transfersArray[$id]->filesOffsets=$value['filesOffsets'];
  488.             if(isset($value['pieces'])) $transfersArray[$id]->pieces=$value['pieces'];
  489.             if(isset($value['pieceLength'])) $transfersArray[$id]->pieceLength=$value['pieceLength'];
  490.             if(isset($value['sentDataLength'])) $transfersArray[$id]->sentDataLength=$value['sentDataLength'];
  491.             if(isset($value['linkedTransferToken'])) $transfersArray[$id]->linkedTransferToken=$value['linkedTransferToken'];
  492.             if(isset($value['size'])) $transfersArray[$id]->size=$value['size'];
  493.             if(isset($value['trackerIdSet'])) $transfersArray[$id]->trackerIdSet=$value['trackerIdSet'];
  494.             if(isset($value['userId'])) $transfersArray[$id]->userId=$value['userId'];
  495.             // Detect aborted downloads
  496.             if($transfersArray[$id]->type=='download' && $transfersArray[$id]->status==3 && (time()-$transfersArray[$id]->lastUpdated)>(2*$transfersArray[$id]->updateInterval)) {
  497.                 $transfersArray[$id]->status=6;
  498.                 $transfersArray[$id]->progress=0;
  499.             }
  500.             if(isset($value['destinationDir'])) $transfersArray[$id]->destinationDir=str_replace('\\','/',$value['destinationDir']);
  501.             if(isset($value['destinationFile'])) {$transfersArray[$id]->destinationFile=str_replace('\\','/',$value['destinationFile']);$transfersArray[$id]->sourceFile=basename($value['destinationFile']); }
  502.             if(isset($value['sourceFile'])) $transfersArray[$id]->sourceFile=$value['sourceFile'];
  503.             if(isset($value['url'])) $transfersArray[$id]->URL=$value['url'];
  504.             if(isset($value['host'])) $transfersArray[$id]->host=$value['host'];
  505.             if(isset($value['path'])) $transfersArray[$id]->path=$value['path'];
  506.  
  507.             // Validate loaded data
  508.             if(!isset($value['sessionId']) || !isset($value['sessionIP']) || !isset($value['status']) || !isset($value['progress'])) unset($transfersArray[$id]);
  509.             switch ($value['type']){
  510.                 case 'upload':
  511.                     if(!isset($value['destinationFile']) || !isset($value['sourceFile']) || !isset($value['destinationDir'])) unset($transfersArray[$id]);
  512.                     break;
  513.                 case 'download':
  514.                     if(!isset($value['destinationFile']) || !isset($value['sourceFile']) || !isset($value['lastUpdated'])) unset($transfersArray[$id]);
  515.                     break;
  516.                 case 'multipleDownload':
  517.                     if(!isset($value['destinationFile']) || !isset($value['sourceFile']) || !isset($value['lastUpdated'])) unset($transfersArray[$id]);
  518.                     break;
  519.                 case 'remoteDownload':
  520.                     if(!isset($value['destinationFile']) || !isset($value['destinationDir']) || !isset($value['host']) || !isset($value['url']) || !isset($value['path'])) unset($transfersArray[$id]);
  521.                     break;
  522.                 case 'bittorrentDownload':
  523.                     if(!isset($value['sourceFile']) || !isset($value['infoHash']) || !isset($value['filesOffsets']) || !isset($value['pieces']) || !isset($value['pieceLength'])) unset($transfersArray[$id]);
  524.                     break;
  525.                 default:
  526.                     unset($transfersArray[$id]);
  527.             }
  528.         }
  529.     }
  530.     unset($parsedFile); unset($parsedFile2);
  531.  
  532.     // Save loaded transfers into memory
  533.     cfMSetVar('weezoTransfers',$transfersArray);
  534.     return $transfersArray;
  535. }
  536.  
  537. /**
  538.  * @desc Inform that a new file upload is about to start
  539.          generate an ID for this upload
  540.          add it to transfers list
  541.  *
  542.  * @param string $directory : directory where file should be uploaded
  543.  * @param string $fileName : uploaded file name
  544.  * @return transfer : created transfer
  545.  */
  546. function tAddUpload($directory, $fileName){
  547.     //if(!cfFileRights($directory=cfCleanPathName($directory),'write')) return false;
  548.     $tr=new transfer('upload');
  549.     $tr->sourceFile=$fileName;
  550.     $tr->destinationDir=$directory;
  551.     $tr->destinationFile=$fileName;
  552.     $tr->status=3;
  553.     $tr->progress='U';
  554.     $tr->commitToFile();
  555.     return $tr;
  556. }
  557.  
  558. /**
  559.  * @desc Inform that a new file download is starting
  560.          generate an ID for this download
  561.          add it to transfers list
  562.  *
  563.  * @param string $fileName : downloaded file name
  564.  * @return transfer : created transfer
  565.  */
  566. function tAddDownload($fileName){
  567.     $tr=new transfer('download');
  568.     $tr->sourceFile=$fileName;
  569.     $tr->destinationFile=basename($fileName);
  570.     $tr->status=3;
  571.     $tr->progress=0;
  572.     $tr->commitToFile();
  573.     return $tr;
  574. }
  575.  
  576. /**
  577.  * @desc Inform that a new file upload is about to start
  578.          generate an ID for this upload
  579.          add it to transfers list
  580.  *
  581.  * @param string $directory : directory where file should be uploaded
  582.  * @param string $fileName : uploaded file name
  583.  * @return transfer : created transfer
  584.  */
  585. function tAddRemoteDownload($dir, $url){
  586.     //if(!cfFileRights($directory=cfCleanPathName($directory),'write')) return false;
  587.  
  588.     // Check passed URL
  589.     $parsed=@parse_url($url);
  590.     if(!(isset($parsed['host'])) || !isset($parsed['path'])) return false;
  591.  
  592.     // Create transfer object
  593.     $tr=new transfer('remoteDownload');
  594.     $tr->sourceFile=basename($parsed['path']);
  595.     $tr->destinationDir=cfCleanPathName($dir);
  596.     $tr->destinationFile=rawurldecode(basename($parsed['path']));
  597.     $tr->URL=$url;
  598.     $tr->host=$parsed['host'];
  599.     $tr->path=$parsed['path'];
  600.     $tr->status=2;
  601.     $tr->lastUpdated=time();
  602.     $tr->progress=0;
  603.     //$tr->commitToFile();
  604.  
  605.     // Generate command string
  606.     $command='transfer transferId="'.$tr->id.'" type="remoteDownload" action="start" destinationDir="'.$dir.'" url="'.$url.'" host="'.$parsed['host'].'" path="'.$parsed['path'].'" startTime="'.$tr->startTime.'" lastUpdated="'.$tr->lastUpdated.'" destinationFile="'.$tr->destinationFile.'"';
  607.     if(isset($parsed['user'])) $command=$command.' user="'.$parsed['user'].'"';
  608.     if(isset($parsed['pass'])) $command=$command.' pass="'.$parsed['pass'].'"';
  609.     if(isset($parsed['query'])) $command=$command.' query="'.$parsed['query'].'"';
  610.  
  611.     // Send command to application to generate and start transfer
  612.     if(!cfServerSendCommand($command)) return false;
  613.     return $tr;
  614. }
  615.  
  616. /**
  617.  * @desc Create new bittorrent download
  618.  *
  619.  * @param array $files : array of files and folders to include in torrent
  620.  * @param string $metainfo: binary content of .torrent file
  621.  * @param array $linkedTransferToken: id of linked directLink or publishDownload token
  622.  * @param array $options: jsSyncMonitorFunction=>javascript function name: async update progress passing progress percentage (0-100)
  623.  * @return transfer: created transfer, false if failure
  624.  */
  625. function tAddBittorrentDownload($files, &$metainfo, $linkedTransferToken=false,$options=array()){
  626.  
  627.     // Create File_Bittorrent_MakeTorrent object
  628.  
  629.     $version=2; // fileBittorrent library version
  630.     if ($version==1){
  631.         require_once(INCLUDE_DIR.'fileBittorrent/MakeTorrent.php');
  632.         $MakeTorrent = new File_Bittorrent_MakeTorrent($files);
  633.     }
  634.     elseif($version==2){
  635.         require_once(INCLUDE_DIR.'File/Bittorrent2/MakeTorrent.php');
  636.         $MakeTorrent = new File_Bittorrent2_MakeTorrent($files);
  637.     }
  638.  
  639.     // Set the announce URL
  640.  
  641.     // Registered users : use weezo.net as tracker
  642.     if($regInfo=cfIsRegistered())
  643.         $trackerURL='http://weezo.net:80/tracker.php?userName='.$regInfo['regName'].'&lng='.cfGGetVar('language');
  644.     // Else, use server as tracker
  645.     else
  646.         $trackerURL=cfGGetVar('hostName').'/bittorrentTracker.php?lng='.cfGGetVar('language');
  647.  
  648.     $trackerURL.='&bittorrentPort='.cfGGetVar('bittorrentPort');
  649.  
  650.     $MakeTorrent->setAnnounce($trackerURL);
  651.  
  652.     // Set the comment
  653.     $MakeTorrent->setComment('Generated by Weezo on '.date(cfCaption('_FULL_DATE_FORMAT')));
  654.  
  655.     // Set the piece length (in KB)
  656.     $MakeTorrent->setPieceLength(1024);
  657.  
  658.     // Set the piece length (in KB)
  659.     //$MakeTorrent->setIsPrivate();
  660.  
  661.     // Set Javascript monitoring function
  662.     if(isset($options['jsSyncMonitorFunction'])) $MakeTorrent->setJsSyncMonitorFunction($options['jsSyncMonitorFunction']);
  663.  
  664.     // Build the torrent
  665.     $metainfo = $MakeTorrent->buildTorrent($files);
  666.  
  667.     if(!$metainfo) return false;
  668.  
  669.     // Create transfer
  670.     $tr=new transfer('bittorrentDownload');
  671.     $tr->destinationFile=$MakeTorrent->torrentName;
  672.     $tr->infoHash=$MakeTorrent->infoHash;
  673.  
  674.     // Generate source files list
  675.     $str=''; foreach ($files as $file) $str.=$file.'|';
  676.     $tr->sourceFile=$str;
  677.  
  678.     // Generate files/offset data
  679.     $str=''; foreach ($MakeTorrent->files as $file) $str.=$file['name'].'?'.$file['offset'].'|';
  680.  
  681.     $tr->filesOffsets=$str;
  682.     $tr->pieces=(strlen($MakeTorrent->pieces)/20);
  683.     $tr->pieceLength=$MakeTorrent->piece_length;
  684.     $tr->size=$MakeTorrent->dataLength;
  685.     $tr->status=2;
  686.     $tr->progress=0;
  687.     $tr->sentDataLength=0;
  688.     $tr->userId=cfUGetVar('id');
  689.     $tr->linkedTransferToken=$linkedTransferToken;
  690.     $tr->commitToFile();
  691.     return $tr;
  692. }
  693.  
  694. /**
  695.  * @desc Inform that a new multiple (zip) download is starting
  696.          generate an ID for this download
  697.          add it to transfers list
  698.  *
  699.  * @param string $outputFilename : zip file name
  700.  * @return transfer : created transfer
  701.  */
  702. function tAddMultipleDownload($outputFilename){
  703.     $tr=new transfer('multipleDownload');
  704.  
  705.     // Generate source files list
  706.     $str='';
  707.     $sfl=cfRGetVar('mDownloadList');
  708.     if(is_array($sfl) && @count($sfl)) foreach (array_values($sfl) as $file) $str.=$file.'|';
  709.     $tr->sourceFile=$str;
  710.  
  711.     // Get total unziped size
  712.     if(cfHGetVar('mDownloadPrecomputeSize')) list($nbFiles,$tr->size)=cfRGetVar('mDownloadTotals'); else $tr->size=0;
  713.  
  714.     $tr->destinationFile=($outputFilename);
  715.     $tr->status=3;
  716.     $tr->progress=0;
  717.     $tr->commitToFile();
  718.     return $tr;
  719. }
  720.  
  721. /*
  722.  ***************************************************************************************************************************
  723.  * Transfer pages
  724.  ***************************************************************************************************************************
  725.  */
  726.  
  727.  
  728. /**
  729.  * @desc display transfers page
  730.  *
  731.  * @param boolean $standalone : true if page should include html head and body
  732.  * @param string $bodyClass optional : class of body
  733.  */
  734. function tDisplayTransfers($standalone, $bodyClass=false){
  735.     if(!isset($_ENV['configurationEnvironment'])) $_ENV['configurationEnvironment']='browser';
  736.  
  737.     require_once(INCLUDE_DIR.'outputFunctions.php');
  738.     // read transfers from files
  739.     $transfersArray=tReadTransfersFiles();
  740.  
  741.     /*
  742.      ***************************************************************************************************************************
  743.      * Process POST Commands
  744.      ***************************************************************************************************************************
  745.      */
  746.  
  747. // Command sent through StandardComForm
  748. if(isset($_POST['data2']) && isset($_POST['data3'])){
  749.     if($standalone) $asyncResponse=true; else $asyncResponse=false;
  750.     $tId=cfUTF8Decode($_POST['data2']); $action=cfUTF8Decode($_POST['data3']);
  751.     if($tId=='all' && ($action=='clear' || $action=='kill')) {
  752.         foreach ($transfersArray as $key=>$value){
  753.             if(cfUGetVar('administrator') || $value->sessionId==wSession_id() || cfIsInApp()){
  754.                 $value->clear($action=='kill');
  755.             }
  756.         }
  757.         //sleep(1);
  758.         tWritePHPTransfersFile($transfersArray);
  759.         if($asyncResponse){
  760.             cfAsyncHeader();
  761.             echo cfAsyncXMLJSaction('if(dgi("transfersIFrame")) frames["transfersIFrame"].refresh();');
  762.             echo cfAsyncFooter();
  763.             exit();
  764.         }
  765.     }
  766.     // Check if transfer exists and user is allowed to interact
  767.     elseif(isset($transfersArray[$_POST['data2']]) && (cfUGetVar('administrator') || $transfersArray[$_POST['data2']]->sessionId==wSession_id() || cfIsInApp())){
  768.         $transfer=$transfersArray[$_POST['data2']];
  769.         // STOP (unfinished) transfer
  770.         if($_POST['data3']=='stop') {$transfer->stop(); $transfer->commitToFile();}
  771.         if($_POST['data3']=='clear') {$transfer->clear(); $transfer->commitToFile();}
  772.         // If transfer is not an upload, let 1 sec to server to remove transfer from file
  773.         if($transfer->type=='remoteDownload') sleep(1);
  774.         // Re-read transfers file
  775.         unset($transfersArray); $transfersArray=tReadTransfersFiles();
  776.     }
  777. }
  778. // Async refresh requested
  779. elseif (isset($_POST['refresh'])) $asyncResponse=true;
  780. // Else, display full page
  781. else $asyncResponse=false;
  782.  
  783.  
  784.     /*
  785.      ***************************************************************************************************************************
  786.      * IFRAME page
  787.      ***************************************************************************************************************************
  788.      */
  789.     if($standalone){
  790.     /*
  791.      * HEAD
  792.      */
  793.  
  794.         // Normal (non-async) page head
  795.         if(!$asyncResponse){
  796.             $_ENV['winNoBar']=true;
  797.             cfInsertHEAD(false);
  798.  
  799.             // Javascript stuff...
  800. ?>
  801. <script language="javascript" type="text/javascript">
  802. var interval;
  803. function refresh(reupdate) {
  804.     window.clearInterval(interval); interval=false;
  805.     if(!window.sendData) {};
  806.     sendData("refresh=true","<?php echo $_SERVER['PHP_SELF'];?>",false);
  807.     if(reupdate) interval=window.setInterval('refresh(false)',2000);
  808. }
  809. function updateInterval(newInterval){
  810.     if(interval) window.clearInterval(interval);
  811.     interval = window.setInterval("refresh()",newInterval);
  812. }
  813. function stop(id){fillAndSubmit(id,'stop');}
  814. function tClear(id){fillAndSubmit(id,'clear');}
  815. function jsConv(str){return str.replace(/<br>/gi,String.fromCharCode(10));}
  816. </script>
  817. </head>
  818. <?php
  819.             // Body
  820.             if($bodyClass) echo '<body class="'.$bodyClass.'" style="margin:0px;border:0px;padding:0px">'; else echo '<body>';
  821.             // Inser standard com form
  822.             outInsertStandardComForm($_SERVER['PHP_SELF'],false,false,false,false,false,true);
  823.             echo '<div id="content" style="height:95%"'.outEHoverFrameAttr().'>';
  824.         }
  825.  
  826.         // Async response header
  827.         else cfAsyncHeader();
  828.  
  829.  
  830.     /*
  831.      * BODY
  832.      */
  833.         // Display transfers
  834.         $displayedTransfers=0; $needRefresh=false;$output='';
  835.         if(is_array($transfersArray)){
  836.             $output.= outTableTransparent(false,'table-layout:fixed');
  837.             $output.= '<colgroup><col width="40"><col width="20"><col width="180"><col width="*"><col width="20"></colgroup>';
  838.             // Display transfer if it belongs to user or if user is administrator
  839.             foreach ($transfersArray as $id=>$transfer) if($transfer->status!=9){
  840.                 if(cfUGetVar('administrator') || $transfer->sessionId==wSession_id()){
  841.                     $output.='<tr id="tr'.$displayedTransfers.'" class="eTC" eH=1 style="padding-left:0.5em;cursor:default">'."\n";
  842.                     // Transfer Icon
  843.                     if($transfer->type=='upload') $output.='<td>'.outImage(outIcon('upload'),false,'title="'.cfCaption('genFileUpload').'"').'</td>';
  844.                     elseif($transfer->type=='remoteDownload') $output.= '<td>'.outImage(outIcon('ddl'),false,'title="'.cfCaption('genDirectDownload').'"').'</td>';
  845.                     elseif($transfer->type=='download') $output.= '<td>'.outImage(outIcon('tdl'),false,'title="'.cfCaption('transfersDownload').'"').'</td>';
  846.                     elseif($transfer->type=='multipleDownload') $output.= '<td>'.outImage(outIcon('tmdl'),false,'title="'.cfCaption('explorerMultipleDownload').'"').'</td>';
  847.                     elseif($transfer->type=='bittorrentDownload') $output.= '<td>'.outImage(outIcon('tbtdl'),false,'title="'.cfCaption('bittorrent').'"').'</td>';
  848.                     // Detail button
  849.                     $output.= '<td>'.outButtonSmall('', 'javascript:alert(jsConv(\''.addslashes($transfer->detail(false)).'\'))', outIcon('info'), cfCaption('genDetails')).'</td>';
  850.                     // Progress bar
  851.                     $output.= '<td>'.$transfer->tProgressBar('180px').'</td>';
  852.                     // File name
  853.                     $output.= '<td style="width:100%;padding-left:0.5em; position:relative;;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">'.cfUTF8Encode(basename($transfer->destinationFile)).'</td>';
  854.                     // Clear finished transfers
  855.                     if($transfer->status==4 || $transfer->status==6 || $transfer->status==8) $output.= '<td>'.outButtonSmall('','javascript:tClear(\''.$transfer->id.'\')',outIcon('eraser'),cfCaption('transferRemove')).'</td>';
  856.                     // Stop transfer
  857.                     elseif($transfer->progress!=1 || $transfer->type=='bittorrentDownload') $output.= '<td>'.outButtonSmall('','javascript:stop(\''.$transfer->id.'\')',outIcon('cancel'),cfCaption('genCancel')).'</td>';
  858.                     else $output.= '<td></td>';
  859.  
  860.                     $output.= "</tr>\n";
  861.                     if($transfer->needRefresh()) $needRefresh=true;
  862.                     $displayedTransfers++;
  863.                 }
  864.             }
  865.             $output.="</table>\n";
  866.         }
  867.         // If no transfer, display "no transfer" message
  868.         if(!$displayedTransfers){
  869.                 $output=''; // reset output
  870.                 $output.= outTableTransparent($bodyClass,false, 'height="95%" width="100%", id="noTransferTable"');
  871.                 $output.= '<tr><td height="100%" valign="middle" align="center">'.cfCaption('activityNoTransfer')."</td></tr></table>\n";
  872.         }
  873.  
  874.         // Flush page to output (XML response or HTML page)
  875.         cfAsyncOutputFlush($output,$asyncResponse,false,'<innerHTML nodeId="content">',false);
  876.  
  877.         // if at least one tranfer is active, indicate that page need to be (async) reloaded in a few seconds, else set to transferIdleRefreshRate
  878.         if($needRefresh) $interval=max(cfHGetVar('transferRefreshRate',2.5)*1000,1000); else $interval=cfHGetVar('transferIdleRefreshRate',10)*1000;
  879.         if($asyncResponse)
  880.             echo cfAsyncXMLJSaction('updateInterval('.$interval.')');
  881.         else
  882.             echo '<script language="javascript" type="text/javascript">updateInterval('.$interval.");</script>\n";
  883.     /*
  884.      * FOOTER
  885.      */
  886.         if($asyncResponse) echo cfAsyncFooter(); else echo '</div></body></html>';
  887.     }
  888.  
  889.  
  890.  
  891.     /*
  892.      ***************************************************************************************************************************
  893.      * Administration / Application page
  894.      ***************************************************************************************************************************
  895.      */
  896.     else{
  897.         // Javascript stuff...
  898.         echo '<script language="javascript" type="text/javascript">'."\nvar interval;\n";
  899.         echo 'function refresh() {window.clearInterval(interval);sendData("refresh=true","'.$_SERVER['PHP_SELF'].'",false);}';
  900.         ?>
  901. function stop(id){fillAndSubmit(id,'stop');}
  902. function tClear(id){fillAndSubmit(id,'clear');}
  903. function jsConv(str){return str.replace(/<br>/gi,String.fromCharCode(10));}
  904.         <?php
  905.         echo "</script>\n";
  906.         // Insert standard com form
  907.         outInsertStandardComForm($_SERVER['PHP_SELF']);
  908.  
  909.         // Display transfers
  910.         $displayedTransfers=0; $needRefresh=false;$output='';
  911.         if(is_array($transfersArray)){
  912.             $output.=outTableTransparent((cfIsInApp())?'frame1':'',false,'');
  913.             $output.= '<colgroup><col width="50"><col width="80"><col width="160"><col width="70"><col width="200"><col width="*"><col width="45"><col width="45"></colgroup>';
  914.             // Display transfer if it belongs to user or if user is     administrator    (note : only administrator can access this script)
  915.             foreach ($transfersArray as $id=>$transfer) if($transfer->status!=9){
  916.                 if(cfUGetVar('administrator') || (cfIsInApp()) || $transfer->sessionId==wSession_id()){
  917.                     $output.='<tr id="tr'.$displayedTransfers.'" class="eTC" eH=1 style="padding-left:0.5em;cursor:default;margin-bottom:10px" align="left">'."\n";
  918.                     // Transfer Icon
  919.                     $output.='<td class="eTCLeft">';
  920.                     if($transfer->type=='upload') $output.=outImage(outIcon('upload'),false,'title="'.cfCaption('genFileUpload').'"').'</td>';
  921.                     elseif($transfer->type=='remoteDownload') $output.=outImage(outIcon('ddl'),false,'title="'.cfCaption('genDirectDownload').'"').'</td>';
  922.                     elseif($transfer->type=='download') $output.=outImage(outIcon('tdl'),false,'title="'.cfCaption('transfersDownload').'"').'</td>';
  923.                     elseif($transfer->type=='multipleDownload') $output.=outImage(outIcon('tmdl'),false,'title="'.cfCaption('explorerMultipleDownload').'"').'</td>';
  924.                     elseif($transfer->type=='bittorrentDownload') $output.=outImage(outIcon('tbtdl'),false,'title="'.cfCaption('bittorrent').'"').'</td>';
  925.                     // Transfer date
  926.                     $output.='<td>'.date(cfCaption('_FULL_DATE_FORMAT'),$transfer->startTime).' </td>';
  927.                     // Transfer source
  928.                     $output.='<td>'.cfCaption('transferCfgSource').' : '.$transfer->sessionIP.'</td>';
  929.                     // Transfer Status
  930.                     $output.='<td>'.$transfer->captionStatus().'</td>';
  931.                     // Progress bar
  932.                     if(cfIsInApp()) $output.='<td height=40><div style="padding-top:2px">'.$transfer->tProgressBar('280px').'</div>';
  933.                     else $output.= '<td>'.$transfer->tProgressBar('280px').'</td><td>';
  934.                     // Source URL, complete destination file name
  935.                     if($transfer->type=='upload') $output.= '<span style="margin-left:0.5em">'.cfUTF8Encode($transfer->sourceFile).' -> '.cfUTF8Encode(str_replace('\\','/',$transfer->destinationFile)).'</span></td>';
  936.                     elseif($transfer->type=='remoteDownload') $output.= '<span style="margin-left:0.5em;">'.cfUTF8Encode(basename($transfer->host)).' -> '.cfUTF8Encode(str_replace('\\','/',$transfer->destinationFile)).'</span></td>';
  937.                     elseif($transfer->type=='download') $output.= '<span style="margin-left:0.5em">'.cfUTF8Encode($transfer->sourceFile).'</span></td>';
  938.                     if(cfIsInApp()) $output.='<td> </td>';
  939.  
  940.                     // Clear finished transfers
  941.                     if($transfer->status==4 || $transfer->status==6 || $transfer->status==8) $output.= '<td nowrap="nowrap">'.outButton('','javascript:tClear(\''.$transfer->id.'\')',outIcon('eraser'),cfCaption('transferRemove')).'</td>';
  942.                     // Stop transfer
  943.                     elseif($transfer->progress!=1) $output.= '<td nowrap="nowrap">'.outButton('','javascript:stop(\''.$transfer->id.'\')',outIcon('cancel'),cfCaption('genCancel')).'</td>';
  944.                     else $output.= '<td> </td>';
  945.                     // Detail button
  946.                     $output.= '<td class="eTCRight" nowrap="nowrap"><span style="display:none" id="hlpLb'.$id.'">'.$transfer->detail(false).'</span>'.outButton('', 'javascript:alert(jsConv(dgi(\'hlpLb'.$id.'\').innerHTML))', outIcon('info'), cfCaption('genDetails')).'</td>';
  947.                     $output.= "</tr>\n";
  948.                     if(cfIsInApp()) $output.='<tr height=3><td></td></tr>';
  949.                     if($transfer->needRefresh()) $needRefresh=true;
  950.                     $displayedTransfers++;
  951.                 }
  952.             }
  953.             $output.="</table><br>\n";
  954.         }
  955.         // If no transfer, display "no transfer" message
  956.         if(!$displayedTransfers){
  957.                 $output=''; // reset output
  958.                 $output.= '<span style="padding-top:14em;padding-bottom:14em;text-align:center;display:block">'.cfCaption('activityNoTransfer')."</span>\n";
  959.         }
  960.         // Flush page to output (XML response or HTML page)
  961.         cfAsyncOutputFlush($output,$asyncResponse,false,false,false);
  962.     }
  963.     return $displayedTransfers;
  964. }
  965.  
  966. /**
  967.  * @desc remove a transfer from transfers list
  968.  *
  969.  * @param string $transferId: id of transfer to remove
  970.  */
  971. function tRemoveTransfer($transferId){
  972.     $transfersArray=tReadTransfersFiles();
  973.     if(isset($transfersArray[$transferId])){
  974.         $transfersArray[$transferId]->clear(true);
  975.         tWritePHPTransfersFile($transfersArray,true);
  976.     }
  977. }
  978. ?>